﻿using System;
using System.Collections.Generic;
using System.Text;
using SharpSvn;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using SharpSvn.Security;
using System.Windows.Input;
using AliyunMobileTestTechnology.ViewModel.Commands;
using System.ComponentModel;
using AliyunMobileTestTechnology.Model;

namespace AliyunMobileTestTechnology.ViewModel
{
    public class RepositoriesViewModel : INotifyPropertyChanged
    {
        public SvnStructureViewModel currentNode;

        public SvnStructureViewModel CurrentNode 
        {
            set 
            {
                currentNode = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler.Invoke(this, new PropertyChangedEventArgs("CurrentNode"));
                }
            }
            get 
            {
                return currentNode;
            }
        }

        public SvnStructureViewModel SelectedNode { set; get; }

        public ICommand SvnCommitChanges 
        {
            get { return new SvnCommitChangesCommand(this); }
        }

        public ICommand SvnCheckOut 
        {
            get { return new SvnCheckOutCommand(this); }
        }

        public ICommand SvnGetDirectories 
        {
            get { return new SvnGetDirectoriesCommand(this); }
        }

        public ICommand SvnUpdate 
        {
            get { return new SvnUpdateCommand(this); }
        }

        public void UpdateWorkingCopy(string path) 
        {
            using (SvnClient svnClient = new SvnClient())
            {
                SetAuthentication(svnClient);
                try
                {
                    if (!svnClient.Update(path))
                    {
                        this.OnSvnExecutedFailed.Invoke("更新工作目录失败.");
                    }
                }
                catch (Exception ex) 
                {
                    this.OnSvnExecutedFailed.Invoke("更新工作目录时发生异常： "+ex.Message);
                }
            }
        }

        public void CheckOut(string url) 
        {
            using (SvnClient svnClient = new SvnClient())
            {
                SetAuthentication(svnClient);
                try
                {
                    if (!svnClient.CheckOut(SvnUriTarget.FromString(url),SettingsViewModel.WorkSpaceConfigValue))
                    {
                        this.OnSvnExecutedFailed.Invoke("签出工作目录失败.");
                    }
                }
                catch (Exception ex)
                {
                    this.OnSvnExecutedFailed.Invoke("签出工作目录时发生异常： " + ex.Message);
                }
            }
        }

        public void CommitChanges(string path) 
        {
            using (SvnClient svnClient = new SvnClient())
            {
                SetAuthentication(svnClient);
                try
                {
                    if (!svnClient.Commit(path))
                    {
                        this.OnSvnExecutedFailed.Invoke("提交文件失败.");
                    }
                }
                catch (Exception ex)
                {
                    this.OnSvnExecutedFailed.Invoke("提交文件时发生异常： " + ex.Message);
                }
            }
        }

        public bool IsWorkingCopy(string path) 
        {
            using (SvnClient svnClient = new SvnClient())
            {
                SetAuthentication(svnClient);
                try
                {
                    var uri = svnClient.GetUriFromWorkingCopy(path);
                    return uri != null;
                }
                catch (Exception ex)
                {
                    this.OnSvnExecutedFailed.Invoke("提交文件时发生异常： " + ex.Message);
                    return false;
                }
            }
        }

        private void SetAuthentication(SvnClient svnClient) 
        {
            svnClient.Authentication.Clear();
            svnClient.Authentication.DefaultCredentials = new NetworkCredential("SvnAdmin", "Aliyun123", "ALIBABA_65235N");
            svnClient.Authentication.SslServerTrustHandlers += delegate(object sender, SvnSslServerTrustEventArgs e)
            {
                e.AcceptedFailures = e.Failures;
                e.Save = true;
            };
        }

        public void GetDirectories() 
        {
            string url;
            if (SelectedNode != null)
            {
                if (SelectedNode.Type == StructureType.File) 
                {
                    return;
                }
                url = SelectedNode.Path;
                SelectedNode.Children.Clear();
                if (SelectedNode.Parent != null)
                {
                    SvnStructureViewModel child = new SvnStructureViewModel();
                    child.Name = "[..]";
                    child.Path = SelectedNode.Parent.Path;
                    child.Type = SelectedNode.Parent.Type;
                    child.Parent = SelectedNode.Parent.Parent;
                    SelectedNode.Children.Add(child);
                }
                // 这个赋值必须放在最后
                CurrentNode = SelectedNode;
            }
            else 
            {
                url = SettingsViewModel.RepositoryUriConfigValue;
            }
            using (SvnClient svnClient = new SvnClient())
            {
                Collection<SvnListEventArgs> contents;
                SetAuthentication(svnClient);
                try
                {
                    if (svnClient.GetList(new Uri(url), out contents))
                    {
                        if (currentNode == null)
                        {
                            SvnStructureViewModel temp = new SvnStructureViewModel();
                            string[] arr=url.Replace('/','\\').Split('\\');
                            temp.Name = arr[arr.Length - 1];
                            temp.Path = url;
                            temp.Type = StructureType.Directory;
                            // 此处赋值触发属性变更消息通知
                            CurrentNode = temp;
                        }
                        foreach (SvnListEventArgs item in contents)
                        {
                            if (item.Path.Length > 0)
                            {
                                SvnStructureViewModel child = new SvnStructureViewModel();
                                child.Name = item.Name;
                                child.Path = item.Uri.OriginalString;
                                child.Type = item.Entry.NodeKind == SvnNodeKind.Directory ? StructureType.Directory : StructureType.File;
                                child.Parent = currentNode;
                                CurrentNode.Children.Add(child);
                            }
                        }
                       
                    }
                    else
                    {
                        this.OnSvnExecutedFailed.Invoke("获取目录信息失败。");
                    }
                }
                catch (Exception ex) 
                {
                    this.OnSvnExecutedFailed.Invoke("获取目录信息时发生异常： " + ex.Message);
                }
            }
        }

        public delegate void SvnExecutedFailedEventHandler(string message);
        public event SvnExecutedFailedEventHandler OnSvnExecutedFailed;

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
